package mips.instructions;

/**
 * <code>LUI</code> instruction<br/>
 * Load Upper Immediate<br/>
 * @author jnmartin84@gmail.com
 */
public class LUI extends Instruction {

	private static LUI INSTANCE = new LUI();
	private static final String INSTRUCTION_NAME = "LUI";

	private LUI(){}

	public static LUI getInstance() {
		return INSTANCE;
	}

	/**
	 * <b>Format:</b><br/>
	 * LUI rt, immediate<br/><br/>
	 * <b>Description:</b><br/>
	 * The 16-bit immediate is shifted left 16 bits and concatenated to 16 bits of<br/>
	 * zeros. The result is placed into general register rt. In 64-bit mode, the<br/>
	 * loaded word is sign-extended.<br/><br/>
	 * <b>Operation:</b><br/>
	 * T: GPR[rt] &larr; immediate || 0<sup>16</sup>
	 */
	@Override
	public final void execute(final int instruction) {
		
		final int rt = (instruction >> 16) & 0x0000001F;
		final int immed = Instruction.signExtendH(instruction & 0x0000FFFF);
		
		mips.R4300i.GPR[rt] = immed << 16;
		
		mips.R4300i.PC = mips.R4300i.nPC;
		mips.R4300i.nPC = mips.R4300i.PC + 4;		
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final String emit(final int instruction) {
		
		final int rt = (instruction >> 16) & 0x0000001F;
		final int immed = Instruction.signExtendH((instruction) & 0x0000FFFF);
		
		return	"		mips.CPU.GPR["+rt+"] = "+String.format("0x%08X",(immed<<16))+";\n" + 
				"		\n" + 
				"		mips.CPU.PC = mips.CPU.nPC;\n" + 
				"		mips.CPU.nPC = mips.CPU.PC + 4;";
	}
	 
	/**
	 * {@inheritDoc}
	 */
	@Override
	public final String getName(final int instruction) {
		return getName();
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final String getName() {
		return INSTRUCTION_NAME;
	}
}